<!DOCTYPE html>
<html>
  <head>
    <title>Wrapper Component</title>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/jquery@3.1.1/dist/jquery.js"></script>
    <script src="https://unpkg.com/select2@4.0.3/dist/js/select2.js"></script>

    <link
      rel="stylesheet"
      type="text/css"
      href="https://unpkg.com/select2@4.0.3/dist/css/select2.min.css"
    />
    <style>
      html,
      body {
        font: 13px/18px sans-serif;
      }
      select {
        min-width: 300px;
      }
    </style>
  </head>
  <body>
    <div id="el"></div>

    <!-- using string template here to work around HTML <option> placement restriction -->
    <script type="text/x-template" id="demo-template">
      <div>
        <p>Selected: {{ selected }}</p>
        <select2 :options="options" v-model="selected">
          <option disabled value="0">Select one</option>
        </select2>
      </div>
    </script>

    <script type="text/x-template" id="select2-template">
      <select>
        <slot></slot>
      </select>
    </script>

    <script>
      Vue.component("select2", {
        props: ["options", "value"],
        template: "#select2-template",
        mounted: function() {
          var vm = this;
          $(this.$el)
            // init select2
            .select2({ data: this.options })
            .val(this.value)
            .trigger("change")
            // emit event on change.
            .on("change", function() {
              vm.$emit("input", this.value);
            });
        },
        watch: {
          value: function(value) {
            // update value
            $(this.$el)
              .val(value)
              .trigger("change");
          },
          options: function(options) {
            // update options
            $(this.$el)
              .empty()
              .select2({ data: options });
          }
        },
        destroyed: function() {
          $(this.$el)
            .off()
            .select2("destroy");
        }
      });

      var vm = new Vue({
        el: "#el",
        template: "#demo-template",
        data: {
          selected: 2,
          options: [{ id: 1, text: "Hello" }, { id: 2, text: "World" }]
        }
      });
    </script>
  </body>
</html>
